package com.sanhuo.security.filter;

import com.sanhuo.lib.exception.GlobalException;
import com.sanhuo.security.UserVo;
import com.sanhuo.security.annotation.Jurisdiction;
import com.sanhuo.security.uitls.UserHolder;
import com.sanhuo.utils.basic.BeanUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class PermitFilter {

    @Pointcut("execution(public * com.sanhuo.*.controller.*.*(..))")
    /*切点签名,只对controller层的代码进行拦截*/
    public void beforePointCut() {
    }

    @Before("beforePointCut()")
    public void before(JoinPoint point) {
        //获取被拦截方法上的jurisdiction注解
        Jurisdiction permitTest = getPermit(point);
        //有该注解说明该方法需要进行权限验证,
        // 没有该注解则说明该方法不需要权限验证,继续执行
        if (BeanUtil.isNotNull(permitTest)) {
            //该boolean值最终为true则说明通过权限验证
            Boolean flag = false;
            //通过request请求体的token获取对应的用户信息
            UserVo user = UserHolder.user();
            //如果用户的权限是超级管理员的话直接通过
            if (user.getRole().getId().equals("0000") || user.getRole().getPermit().contains("all_permit")) {
                flag = true;
            }
            //获取jurisdiction注解上所需要的角色
            String[] hasRoles = permitTest.hasRoles();
            //如果所需角色不为空
            if (hasRoles.length > 0) {
                //判断该用户是否有对应角色
                for (String role : hasRoles) {
                    flag |= role.equals(user.getRole().getId());
                }
            }
            //获取jurisdiction注解上所需要的权限
            String[] hasPermit = permitTest.hasPermits();
            //如果所需权限不为空
            if (hasPermit.length > 0) {
                //判断用户是否有对应的权限
                for (String permit : hasPermit) {
                    flag |= user.getRole().getPermit().contains(permit);
                }
            }
            //如果flag最后为false则说明不通过
            if (!flag) {
                throw new GlobalException("权限不足!");
            }
        }
    }

    private Jurisdiction getPermit(JoinPoint point) {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        return targetMethod.getAnnotation(Jurisdiction.class);
    }


}
